package com.roadmap.common;

import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Locale;

public final class BaseConst {
	private static BaseConst _singlton;

	private BaseConst() {
	}

	/** it's only for getting the class path */
	private static BaseConst getInstance() {
		synchronized (BaseConst.class) {
			if (_singlton == null) {
				_singlton = new BaseConst();
			}
			return _singlton;
		}
	}

	/** the company's Internet host */
	public final static String COMPANY_INTERNET_HOST = "http://www.ucdream.com";

	public final static String PURIKURA_DIR_TEMP = "repo/purikura/temp/";
	public final static String PURIKURA_DIR_BIG = "repo/purikura/big/";
	public final static String PURIKURA_DIR_SMALL = "repo/purikura/small/";

	/** the path of rdc.properties file */
	public final static String RDC_PROPERTY_FILE = "rdc.properties";
	public final static String LOG_CONFIG_FILE = "log4j.properties";
	public final static String REPOSITORY_HIBENATE_FILE = "hibernate.cfg.xml";

	// date format
	/** format date to "yyyy-MM-dd hh:mm:ss" */
	public final static SimpleDateFormat DATETIME_FORMAT = new SimpleDateFormat(
			"yyyy-MM-dd hh:mm:ss", Locale.SIMPLIFIED_CHINESE); // date time
	/** format date to "yyyy-MM-dd" */
	public final static SimpleDateFormat DATE_FORMATE = new SimpleDateFormat(
			"yyyy-MM-dd", Locale.SIMPLIFIED_CHINESE); // date time format
	public final static long DayToMillion = 24 * 60 * 60 * 1000;
	public final static long HourToMillion = 60 * 60 * 1000;
	public final static int DaysOfWeek = 7;

	// registration status
	/** registration status: aspirant doesn't pass the registration */
	public final static int REGISTRATION_STATUS_NotPassed = 1;
	/** registration status: aspirant passes the registration */
	public final static int REGISTRATION_STATUS_Passed = 2;

	// aspirant's love type
	/** aspirant's love type: keep it in secret */
	public final static int ASPIRANT_LOVETYPE_Secret = 0;
	/** aspirant's love type: no girlfriend or boyfriend */
	public final static int ASPIRANT_LOVETYPE_NoMate = 1;
	/** aspirant's love type: has girlfriend or boyfriend but not get married */
	public final static int ASPIRANT_LOVETYPE_MateNoMarried = 2;
	/** aspirant's love type: already married */
	public final static int ASPIRANT_LOVETYPE_Married = 3;

	// aspirant's sex
	/** aspirant's sex: he is a man */
	public final static char ASPIRANT_SEX_MALE = 'm';
	/** aspirant's sex: she is a woman */
	public final static char ASPIRANT_SEX_FEMALE = 'f';

	/**
	 * this one is not the real status of a goal, it should not be assigned to a
	 * goal to be saved to database
	 */
	public final static int LIFEGOAL_STATUS_ALL = 0;
	// goal's status
	/** goal's status: the goal has no tasks */
	public final static int LIFEGOAL_STATUS_UNSCHEDULED = 1;
	/** goal's status: the goal has a plan but the no execution */
	public final static int LIFEGOAL_STATUS_SCHEDULED = 2;
	/** goal's status: the goal has executions */
	public final static int LIFEGOAL_STATUS_UNDERGOING = 3;
	/** goal's status: the goal is achieved or completed */
	public final static int LIFEGOAL_STATUS_COMPLETED = 4;
	/** goal's status: the goal is canceled */
	public final static int LIFEGOAL_STATUS_CANCELED = 5;
	/** goal's status: the goal is deleted */
	public final static int LIFEGOAL_STATUS_DELETED = 6;

	/** entity's priority: low */
	public final static int ENTITY_PRIORITY_LOW = 1;
	/** entity's priority: medium */
	public final static int ENTITY_PRIORITY_MEDIUM = 2;
	/** entity's priority: high */
	public final static int ENTITY_PRIORITY_HIGH = 3;

	// the types of relationship between two goals
	/** goal A is a parent of B */
	public final static int LIFEGOAL_RELATION_PATERNAL = 1;
	/** goal A is a kid of B */
	public final static int LIFEGOAL_RELATION_FILIAL = 2;
	/** goal A relies on B */
	public final static int LIFEGOAL_RELATION_RELYON = 3;
	/** goal A is relied on by B */
	public final static int LIFEGOAL_RELATION_RELIEDON = 4;
	/** goals A and B depend on each other */
	public final static int LIFEGOAL_RELATION_INTERDEPENDENT = 5;

	/**
	 * this one is not the real status of a task, it should not be assigned to a
	 * task to be saved to database
	 */
	public final static int LIFETASK_STATUS_ALL = 0;

	// task's statuses
	public final static int LIFETASK_STATUS_SCHEDULED = 1;
	public final static int LIFETASK_STATUS_UNDERGOING = 2;
	public final static int LIFETASK_STATUS_COMPLETED = 3;
	public final static int LIFETASK_STATUS_CANCELED = 4;
	public final static int LIFETASK_STATUS_DELETED = 5;

	// task's ranks
	public final static int LIFETASK_RANK_NotImportantButUrgent = 1;
	public final static int LIFETASK_RANK_ImportantAndUrgent = 2;
	public final static int LIFETASK_RANK_ImportantButNotUrgent = 3;
	public final static int LIFETASK_RANK_NotImportantAndNotUrgent = 4;

	// task's execution cycle
	public final static int LIFETASK_EXECUTION_Once = 1;
	public final static int LIFETASK_EXECUTION_Everyday = 2;
	public final static int LIFETASK_EXECUTION_EveryThreeDays = 3;
	public final static int LIFETASK_EXECUTION_EveryWeek = 4;
	public final static int LIFETASK_EXECUTION_EveryMonth = 5;
	public final static int LIFETASK_EXECUTION_EveryYear = 6;

	// resource's impact rank
	public final static int RESOURCE_RANK_LOW = 1;
	public final static int RESOURCE_RANK_MEDIUM = 2;
	public final static int RESOURCE_RANK_HIGH = 3;

	// resource's status
	public final static int RESOURCE_STATUS_UNSEZIED = 1;
	public final static int RESOURCE_STATUS_SEZIED = 2;

	// risk's impact rank
	public final static int RISK_RANK_LOW = 1;
	public final static int RISK_RANK_MEDIUM = 2;
	public final static int RISK_RANK_HIGH = 3;

	// measurable rule's status
	public final static int RULE_STATUS_UNSATISFIED = 1;
	public final static int RULE_STATUS_SATISFIED = 2;

	// milestone's status
	public final static int MILESTONE_STATUS_UNSATISFIED = 1;
	public final static int MILESTONE_STATUS_SATISFIED = 2;

	// request's status
	public final static int REQUEST_STATUS_NEW = 0;
	public final static int REQUEST_STATUS_APPROVED = 1;
	public final static int REQUEST_STATUS_REJECTED = 2;
	public final static int REQUEST_TYPE_FRIEND = 0;
	public final static int REQUEST_TYPE_SPONSOR = 1;
	public final static int REQUEST_TYPE_MENTOR = 2;

	// visibility rank
	public final static int ENTRY_VISIBILITY_PRIVATE = 0;
	public final static int ENTRY_VISIBILITY_PROTECTED = 1;
	public final static int ENTRY_VISIBILITY_LIMITED = 2;
	
	// relationship type
	public final static int RELEATIONSHIP_TYPE_FRIEND = 0;
	public final static int RELEATIONSHIP_TYPE_SPONSOR = 1;
	public final static int RELEATIONSHIP_TYPE_SPONSORED = 2;
	public final static int RELEATIONSHIP_TYPE_MENTOR = 3;
	public final static int RELEATIONSHIP_TYPE_MENTORED = 4;

	// message type
	public final static int MESSAGE_TYPE_PERSONAL = 0;
	public final static int MESSAGE_TYPE_SYSTEM = 1;

	// message status
	public final static int MESSAGE_STATUS_UNREAD = 0;
	public final static int MESSAGE_STATUS_READ = 1;
	
	// notice status
	public final static int NOTICE_STATUS_UNREAD = 0;
	public final static int NOTICE_STATUS_READ = 1;

	// the separator for member IDs in category
	public final static String CATEGORY_ID_SEPARATOR = ",";

	// the length of article text
	public final static int ARTICLE_LENGTH_ON_UI = 120;

	// the length of automatically generated random string
	public final static int RANDOM_STRING_LENGTH = 6;

	public final static int DATABASE_TABLE_ID_LENGTH = 32;

	/** the servlet URL of getting data charts */
	public final static String CHART_SERVLET_URL = "admin/life/chart?filename=";

	public final static int CHART_AXIS_X_POINTS = 10;

	/**
	 * What kind of mode the application run in. Server mode: the application is
	 * deployed on TOMCAT server
	 */
	public final static String RUN_MODE = getRunMode();

	/** The path of config directory */
	public final static String CONFIG_LOCATION = getConfigLocation();

	// ----------------------------------------------------------------------
	// static methods
	private static String getRunMode() {
		String mode = System.getProperty("rdc.run.mode");
		return (mode != null && (mode.equalsIgnoreCase("direct") || mode
				.equalsIgnoreCase("server"))) ? mode : "server";
	}

	// get the location of the config property file, it's under the same dir as
	// the BaseConst class
	private static String getConfigLocation() {
		String path = getInstance().getClassPath();// System.getProperty("rdc.config.home");
		String location = (path != null) ? (path + "/") : (System
				.getProperty("user.dir") + "/src/");
		return location.replace('\\', '/');
	}

	// get the class path
	private String getClassPath() {
		String strClassName = getClass().getName();
		String strPackageName = "";
		if (getClass().getPackage() != null) {
			strPackageName = getClass().getPackage().getName();
		}

		String strClassFileName = "";
		if (!"".equals(strPackageName)) {
			strClassFileName = strClassName.substring(
					strPackageName.length() + 1, strClassName.length());
		}
		else {
			strClassFileName = strClassName;
		}

		URL url = null;
		url = getClass().getResource(strClassFileName + ".class");
		String strURL = url.toString();
		try {
			strURL = java.net.URLDecoder.decode(strURL, "UTF-8");
		}
		catch (Exception ex) {
			ex.printStackTrace();
		}
		strURL = strURL.substring(strURL.indexOf('/') + 1, strURL
				.lastIndexOf('/'));
		return strURL;
	}
	
	/** the real path of the web application */
	private static String webAppRealPath = null;

	public static String getWebAppRealPath() {
		if(webAppRealPath == null) {
			String path = BaseConst.CONFIG_LOCATION;
			if(path != null && path.indexOf("WEB-INF") != -1) {
				webAppRealPath = path.split("WEB-INF")[0];
			}
		}
		return webAppRealPath;
	}

	// query configuration
	/** max results returned from one query */
	public final static int MAX_RESULTS_IN_QUERY = 15;
	/** max results of notices */
	public final static int NOTICE_MAX_RESULTS = 80;
	/** */
	public final static int NOTICE_OLD_DATE_DIFF = 7;
	/** max results of messages */
	public final static int MESSAGE_MAX_RESULTS = 100;
	
	// placeholders
	public final static String PLACEHOLDER_SERVER_IN_MAIL = "<server_address>";
	
	public final static String PERMISSION_FIELD_NAME = "visibility";
	public final static String PERMISSION_FIELD_METHOD = "getVisibility";
}
